home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.2 Applications 1996 May / SGI IRIX 6.2 Applications 1996 May.iso / dist / impr_dev.idb / usr / impressario / src / libimp / impClose.c.z / impClose.c
C/C++ Source or Header  |  1996-05-06  |  9KB  |  348 lines

  1. /**************************************************************************
  2.  *
  3.  *           Copyright (c)    1993 Silicon Graphics, Inc.
  4.  *            All Rights Reserved
  5.  *
  6.  *       THIS    IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI
  7.  *
  8.  * The copyright notice above does not evidence any actual of intended
  9.  * publication of such source code, and is an unpublished work by Silicon
  10.  * Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is
  11.  * the property of Silicon Graphics, Inc. Any use, duplication or
  12.  * disclosure not specifically authorized by Silicon Graphics is strictly
  13.  * prohibited.
  14.  *
  15.  * RESTRICTED RIGHTS LEGEND:
  16.  *
  17.  * Use, duplication or disclosure by the Government is subject to
  18.  * restrictions as set forth in subdivision (c)(1)(ii) of the Rights in
  19.  * Technical Data and Computer Software clause at DFARS 52.227-7013,
  20.  * and/or in similar or successor clauses in the FAR, DOD or NASA FAR
  21.  * Supplement. Unpublished - rights reserved under the Copyright Laws of
  22.  * the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.
  23.  * Shoreline Blvd., Mountain View, CA 94039-7311
  24.  **************************************************************************
  25.  *
  26.  * File: impClose.c
  27.  *
  28.  * Description: Routines to close an open SGI Image file.
  29.  *
  30.  **************************************************************************/
  31.  
  32.  
  33. #ident "$Revision: 1.7 $"
  34.  
  35.  
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <unistd.h>
  39. #include <assert.h>
  40. #include <errno.h>
  41. #include <sys/types.h>
  42. #include <sys/stat.h>
  43. #include <sys/mman.h>
  44. #include "impI.h"
  45.  
  46.  
  47. /* Local functions */
  48.  
  49. static int closeImage(IMPImage *image, int *fdp);
  50. static int flushImage(IMPImage *image);
  51.  
  52.  
  53. /**************************************************************************
  54.  *
  55.  * Function: impClose
  56.  *
  57.  * Description: Closes an SGI Image file previsouly opened by a call to
  58.  *    impOpen or impOpenFd. Note that the file descriptor for the image
  59.  *    is also closed.
  60.  *
  61.  * Parameters: 
  62.  *    image (I) - image to close
  63.  *
  64.  * Return: 0 if sucessful. -1 is returned and IMPerrno is set if an error
  65.  *    has occurred.
  66.  *
  67.  **************************************************************************/
  68.  
  69. int impClose(IMPImage *image)
  70. {
  71.     int fd;
  72.  
  73.     /*
  74.      * Close the image. The image structure is deallocated
  75.      * and invalid from this point on.
  76.      */
  77.     if (closeImage(image, &fd) < 0)
  78.     _impReturnError(IMPerrno);
  79.  
  80.     /*
  81.      * Close the image file descriptor
  82.      */
  83.     if (fd != -1) {
  84.         if (close(fd) < 0)
  85.         _impReturnError(errno);
  86.     }
  87.  
  88.     return 0;
  89. }
  90.  
  91.  
  92. /**************************************************************************
  93.  *
  94.  * Function: impCloseFd
  95.  *
  96.  * Description: Closes an SGI Image file previsouly opened by a call to
  97.  *    impOpen or impOpenFd. Note that the file descriptor for the image
  98.  *    is left open.
  99.  *
  100.  * Parameters: 
  101.  *    image (I) - image to close
  102.  *    fdp (O) - image file descriptor, left open after call
  103.  *
  104.  * Return: 0 if sucessful. -1 is returned and IMPerrno is set if an error
  105.  *    has occurred.
  106.  *
  107.  **************************************************************************/
  108.  
  109. int impCloseFd(IMPImage *image, int *fdp)
  110. {
  111.     /*
  112.      * Close the image. The image structure is deallocated
  113.      * and invalid from this point on.
  114.      */
  115.     if (closeImage(image, fdp) < 0)
  116.     _impReturnError(IMPerrno);
  117.  
  118.     return 0;
  119. }
  120.  
  121.  
  122. /*
  123.  ============================================================================
  124.             LOCAL FUNCTIONS
  125.  ============================================================================
  126. */
  127.  
  128.  
  129. /**************************************************************************
  130.  *
  131.  * Function: closeImage
  132.  *
  133.  * Description: Closes an SGI Image file previsouly opened by a call to
  134.  *    impOpen but does not close the file descriptor associated with
  135.  *    the image.
  136.  *
  137.  * Parameters: 
  138.  *    image (I) - image to close
  139.  *    fdp (O) - image file descriptor
  140.  *
  141.  * Return: 0 if sucessful. -1 is returned and IMPerrno is set if an error
  142.  *    has occurred.
  143.  *
  144.  **************************************************************************/
  145.  
  146. int closeImage(IMPImage *image, int *fdp)
  147. {
  148.     /*
  149.      * Sanity check the inputs
  150.      */
  151.     assert(image != NULL);
  152.     assert(fdp != NULL);
  153.  
  154.     /*
  155.      * Send back the image file descriptor
  156.      */
  157.     *fdp = image->file;
  158.  
  159.     /*
  160.      * Flush any pending writes
  161.      */
  162.     if (flushImage(image) < 0)
  163.     _impReturnError(IMPerrno);
  164.  
  165.     /*
  166.      * If we are writing the image, write out the current header;
  167.      * if RLE, write the RLE tables; if the image has extension tags, write
  168.      * them as well.
  169.      */
  170.     if (_impWriting(image)) {
  171.     int retv;
  172.     struct stat buf;
  173.     off_t     length, begin;
  174.  
  175.     if(impHasTags(image) ) {
  176.         /* Pretty stupid, but I don't think there's any other way to find
  177.          * the length of this file */
  178.         fstat(image->file, &buf);
  179.         length = buf.st_size;
  180.         begin = (length + 3) & ~0x3;
  181.     } else {
  182.         begin = 0;
  183.     }
  184.     if (image->dorev)
  185.         _impSwapLongs((__uint32_t *) &begin, sizeof(long));
  186.  
  187.     /*
  188.      * Seek to start of file
  189.      */
  190.         if (_impSeekOffset(image, image->start) < 0)
  191.         _impReturnError(IMPerrno);
  192.  
  193.     /*
  194.      * Update the image header on disk, byte swapping
  195.      * if necessary. If we swap we un-swap after the write.
  196.      */
  197.     if (image->dorev)
  198.         _impSwapHeader(image);
  199.     retv = _impWrite(image, image, sizeof(IMPImage));
  200.     if (image->dorev)
  201.         _impSwapHeader(image);
  202.     if (retv != sizeof(IMPImage))
  203.         _impReturnError(IMPerrno);
  204.  
  205.     /* Write the pointer to the start of the extension tags, or 0 if
  206.      * there are no extension tags */
  207.     if (_impSeekOffset(image, IMP_TAG_PTR_OFFSET) < 0)
  208.         _impReturnError(IMPerrno);
  209.     retv = _impWrite(image, &begin, sizeof(long));
  210.     if (image->dorev)
  211.         _impSwapLongs((__uint32_t *) &begin, sizeof(long));
  212.     if (retv != sizeof(long))
  213.         _impReturnError(IMPerrno);
  214.  
  215.  
  216.     /*
  217.      * Write the RLE tables if this is an RLE image
  218.      */
  219.     if (impIsRLE(image)) {
  220.         int rleTableSize;
  221.  
  222.         if (_impSeekOffset(image, image->start + _IMP_TABLES_START) < 0)
  223.         _impReturnError(IMPerrno);
  224.         rleTableSize = impYSize(image) * impNumChannels(image) *
  225.                             sizeof(__int32_t);
  226.         if (image->dorev) {
  227.         _impSwapLongs(image->rowstart, rleTableSize);
  228.         _impSwapLongs((__uint32_t*)image->rowsize, rleTableSize);
  229.         }
  230.         if (_impWrite(image, image->rowstart, rleTableSize) != rleTableSize)
  231.         _impReturnError(IMPerrno);
  232.         if (_impWrite(image, image->rowsize, rleTableSize) != rleTableSize)
  233.         _impReturnError(IMPerrno);
  234.     }
  235.  
  236.     /*
  237.      * Write extension tags, if any 
  238.      */
  239.     if (impHasTags(image)) {
  240.         char    pad[4], *magic = "tags";
  241.         IMPTag    *pTag, *next, dummyTag;
  242.  
  243.         /* Just double-checking */
  244.         fstat(image->file, &buf);
  245. #if 0
  246.         assert(length == buf.st_size);
  247.         /* Seek to the end of the file */
  248.         if (_impSeekOffset(image, length) < 0)
  249.         _impReturnError(IMPerrno);
  250. #else
  251.         /* Seek to the end of the file */
  252.         if (_impSeekOffset(image,  buf.st_size) < 0)
  253.         _impReturnError(IMPerrno);
  254. #endif
  255.         if(begin - length > 0) {    /* pad to start on word boundary */
  256.         if(_impWrite(image, &pad, begin - length) != begin - length)
  257.             _impReturnError(IMPerrno);
  258.         }
  259.         /* Write the extension tag delimiter */
  260.         dummyTag.header.tagname = IMP_TAG_FIRST_TAG;
  261.         dummyTag.header.length = 4;
  262.         if (_impWrite(image, &dummyTag.header, sizeof(IMPTagHeader)) != 
  263.           sizeof(IMPTagHeader))
  264.         _impReturnError(IMPerrno);
  265.         if (_impWrite(image, magic, strlen(magic)) != strlen(magic))
  266.         _impReturnError(IMPerrno);
  267.  
  268.  
  269.         /* write each tag */
  270.         pTag = impTags(image);
  271.         while (pTag) {
  272.         __uint32_t lenTag;
  273.  
  274.         lenTag = pTag->header.length;
  275.         if (_impWrite(image, pTag, sizeof(IMPTagHeader)) !=
  276.            sizeof(IMPTagHeader))
  277.             _impReturnError(IMPerrno);
  278.         if (_impWrite(image, pTag->data, lenTag) != lenTag)
  279.             _impReturnError(IMPerrno);
  280.         next = pTag->next;
  281.         free(pTag->data);
  282.         free(pTag);
  283.         pTag = next;
  284.         }
  285.  
  286.         /* Write the last tag */
  287.         dummyTag.header.tagname = IMP_TAG_LAST_TAG;
  288.         dummyTag.header.length = 0;
  289.         if (_impWrite(image, &dummyTag, sizeof(IMPTagHeader)) != 
  290.           sizeof(IMPTagHeader))
  291.         _impReturnError(IMPerrno);
  292.     }
  293.     }
  294.  
  295.     /*
  296.      * Free any allocated buffer storage
  297.      */
  298.     if (image->base)
  299.     free(image->base);
  300.     if (image->tmpbuf)
  301.     free(image->tmpbuf);
  302.     if (impIsRLE(image)) {
  303.     free(image->rowstart);
  304.     free(image->rowsize);
  305.     }
  306.     if (_impReading(image)) {
  307.         if (image->cache == IMPHeapCache && image->cachebuf)
  308.         free(image->cachebuf);
  309.         if (image->cache == IMPMapCache && image->cachebuf)
  310.         munmap(image->cachebuf, image->cachesize);
  311.     }
  312.  
  313.     /*
  314.      * Blow away the image structure
  315.      */
  316.     free(image);
  317.  
  318.     return 0;
  319. }
  320.  
  321.  
  322. /**************************************************************************
  323.  *
  324.  * Function: flushImage
  325.  *
  326.  * Description: Flushes any pending writes to an image file.
  327.  *
  328.  * Parameters: 
  329.  *    image (I) - image file
  330.  *
  331.  * Return: 0 if successful. -1 and IMPerrno set if errors.
  332.  *
  333.  **************************************************************************/
  334.  
  335. static int flushImage(IMPImage *image)
  336. {
  337.     if (_impWriting(image)) {
  338.         short *base;
  339.  
  340.     if ((base = image->base) != NULL && (image->ptr - base) > 0) {
  341.         if (impWriteRow(image, base, image->y, image->z) != impXSize(image))
  342.         _impReturnError(IMPerrno);
  343.     }
  344.     }
  345.  
  346.     return 0;
  347. }
  348.